
// Created by carolsail 
const { ccclass, property } = cc._decorator;

import { ENUM_GAME_MODE, ENUM_GAME_STATUS, ENUM_UI_TYPE } from "../Enum";
import { StaticInstance } from "../StaticInstance";
import Chess from "../game/Chess";
import DataManager from "./DataManager";
import PoolManager from "./PoolManager";

@ccclass
export default class GameManager extends cc.Component {

    @property([cc.SpriteFrame])
    bgs: cc.SpriteFrame[] = []

    rootGame: cc.Node = null
    rootEffect: cc.Node = null
    boardInfo: cc.Node = null
    boardChess: cc.Node = null
    bgNode: cc.Node = null

    step: number = 0
    kill: number = 0

    onLoad() {
        StaticInstance.setGameManager(this)
        this.rootGame = cc.find('Stage/RootGame', this.node)
        this.rootEffect = cc.find('Stage/RootEffect', this.node)
        this.boardInfo = cc.find('board_info', this.rootGame)
        this.boardChess = cc.find('board_chess', this.rootGame)
        this.bgNode = cc.find('bg', this.rootGame)
        // DataManager.instance.wsClient.listenMsg('GameRefresh', ({ type, content }) => {
        //     if (type == 'msg_dice_play') {
        //         this.onDicePlaySync(content)
        //     } else if (type == 'msg_plane_touch') {
        //         this.onPlaneTouchSync(content)
        //     } else if (type == 'msg_game_over') {
        //         this.onGameOverSync(content)
        //     } else if (type == 'msg_game_chat') {
        //         this.onGameChatSync(content)
        //     } else if (type == 'msg_game_disconnect') {
        //         this.onGameDisconnectSync(content)
        //     }
        // })
    }

    onDestroy() { }

    // 开始游戏
    onGameStart() {
        DataManager.instance.reset()
        this.initGame()
    }

    // 初始化游戏
    initGame() {
        // 初始化数据
        DataManager.instance.status = ENUM_GAME_STATUS.UNRUNING
        this.rootEffect.removeAllChildren()
        this.boardChess.removeAllChildren()
        this.step = 0
        this.bgNode.getComponent(cc.Sprite).spriteFrame = this.bgs[DataManager.instance.bgIndex]
        // 初始化棋子
        this.initChess()
        // ui渲染
        StaticInstance.uiManager.setMainUser()
        StaticInstance.uiManager.setMainTip()
        DataManager.instance.status = ENUM_GAME_STATUS.RUNING
        // 指定塞子
        StaticInstance.uiManager.setMainDice()
    }

    initChess() {
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 4; j++) {
                if (DataManager.instance.posData[i].length) {
                    const pos = DataManager.instance.posData[i][j]
                    const chessNode = PoolManager.instance.getNode('Chess', this.boardChess)
                    const chessComponent = chessNode.getComponent(Chess)
                    chessComponent.init(i, j, pos)
                }
            }
        }
    }

    onDiceStep(step: number = 0) {
        this.step = step
        const chesses = this.getChessArrByStep(step)
        if (chesses.length) {
            if (chesses.length == 1) {
                // 自动化
                // console.log('自动化')
                const chessComponent = chesses[0].getComponent(Chess)
                this.onPlaneStart(chessComponent)
            } else {
                if (DataManager.instance.isAi[DataManager.instance.round]) {
                    const index = this.getAiIndex(chesses)
                    const chessComponent = chesses[index].getComponent(Chess)
                    this.onPlaneStart(chessComponent)
                } else {
                    // 激活
                    this.setChessActive(chesses, true)
                }
            }
        } else {
            // 回合切换
            StaticInstance.uiManager.setMainNotice(0)
            this.onPlaneEnd()
        }
    }

    onPlaneTouch(chessComponent: Chess) {
        // 取消激活
        const chesses = this.getChessArrByStep()
        this.setChessActive(chesses, false)
        // 移动或起飞
        this.onPlaneStart(chessComponent)
    }

    // 飞机动作开始
    onPlaneStart(chessComponent: Chess) {
        chessComponent.move(this.step)
    }

    // 飞机动作结束
    onPlaneEnd(chessComponent: Chess = null, delay: number = 0.3) {
        this.scheduleOnce(() => {
            let isGameOver = false
            if (chessComponent) {
                // 抵达终点
                if (chessComponent.isEndpoint()) {
                    chessComponent.setEndpoint()
                    const chesses = this.getChessArrByStep()
                    const index = chesses.findIndex(chess => !chess.getComponent(Chess).isEndpoint() && chess.getComponent(Chess).type == chessComponent.type)
                    if (index < 0) isGameOver = true
                }
            }
            if (isGameOver) {
                if (DataManager.instance.mode == ENUM_GAME_MODE.SINGLE) {
                    DataManager.instance.status = ENUM_GAME_STATUS.UNRUNING
                    StaticInstance.uiManager.toggle(ENUM_UI_TYPE.OVER)
                } else {
                    const playerActive = DataManager.instance.room.players.find(player => player.status == 1)
                    if (playerActive.openid == DataManager.instance.user.openid) {
                        const room = DataManager.instance.room
                        room.status = 2
                        const params = {
                            type: 'msg_game_over',
                            room: DataManager.instance.room,
                            content: {
                                room
                            }
                        }
                        DataManager.instance.wsClient.callApi('GameSync', params)
                    }
                }
            } else {
                if (this.step == 6) StaticInstance.uiManager.setMainNotice(1)
                this.onRoundTurn(this.step != 6)
                this.step = 0
            }
        }, delay)
    }

    // 飞机碰撞检测
    onPlaneCheck(chessComponent: Chess, jumpType: number = 0) {
        if (chessComponent.isEndpoint()) return
        let chesses = []
        if (jumpType == 3) {
            // 直线跑道或起跑点(只存在同色重叠)
            chesses = this.boardChess.children.filter(chess => chess.getComponent(Chess) != chessComponent && chess.getComponent(Chess).type == chessComponent.type)
            const overlaps: Chess[] = []
            chesses.forEach(chess => {
                const otherComponent = chess.getComponent(Chess)
                if (otherComponent.pos == chessComponent.pos) {
                    if (overlaps.indexOf(chessComponent) == -1) overlaps.push(chessComponent)
                    if (overlaps.indexOf(otherComponent) == -1) overlaps.push(otherComponent)
                }
            })
            // 调整重叠位置
            const { x, y } = chessComponent.node
            overlaps.forEach(item => {
                if (item.index == 0) {
                    item.node.setPosition(x + 5, y)
                } else if (item.index == 1) {
                    item.node.setPosition(x, y + 5)
                } else if (item.index == 2) {
                    item.node.setPosition(x - 5, y)
                } else {
                    item.node.setPosition(x, y - 5)
                }
            })
        } else {
            chesses = this.boardChess.children.filter(chess => chess.getComponent(Chess).isRound() && chess.getComponent(Chess) != chessComponent)
            // 途中碰撞
            if (jumpType == 1) {
                // 普通跳跃
                const prePos = chessComponent.pos - 4
                chesses.forEach(chess => {
                    const otherComponent = chess.getComponent(Chess)
                    if (otherComponent.type != chessComponent.type) {
                        if (chessComponent.getRoundPosBaseRed(prePos) == otherComponent.getRoundPosBaseRed()) {
                            otherComponent.setBorn()
                            this.kill += 1
                        }
                    }
                })
            } else if (jumpType == 2) {
                // pos = 17起飞点
                this.boardChess.children.forEach(other => {
                    if (other != chessComponent.node) {
                        const fp = other.getComponent(Chess).getRoundPosBaseRed()
                        const sp = chessComponent.getRoundPosBaseRed(17)
                        if (fp == sp) {
                            other.getComponent(Chess).setBorn()
                            this.kill += 1
                        }
                    }
                })
                // 飞行跳跃
                const type = (chessComponent.type + 2) % 4
                const lineChesses = this.boardChess.children.filter(chess => chess.getComponent(Chess).type == type && chess.getComponent(Chess).isUnSafeInLine())
                lineChesses.forEach(chess => {
                    chess.getComponent(Chess).setBorn()
                    this.kill += 1
                })
            }
            // 落点碰撞
            const overlaps: Chess[] = []
            chesses.forEach(chess => {
                const otherComponent = chess.getComponent(Chess)
                if (otherComponent.type != chessComponent.type) {
                    // 异色碰撞
                    if (chessComponent.getRoundPosBaseRed() == otherComponent.getRoundPosBaseRed()) {
                        otherComponent.setBorn()
                        this.kill += 1
                    }
                } else {
                    // 同色重叠
                    if (chessComponent.getRoundPosBaseRed() == otherComponent.getRoundPosBaseRed()) {
                        if (overlaps.indexOf(chessComponent) == -1) overlaps.push(chessComponent)
                        if (overlaps.indexOf(otherComponent) == -1) overlaps.push(otherComponent)
                    }
                }
            })
            // 击杀数
            DataManager.instance.killData[chessComponent.type] += this.kill
            this.kill = 0
            StaticInstance.uiManager.setMainKill(chessComponent.type)
            // 调整重叠位置
            const { x, y } = chessComponent.node
            overlaps.forEach(item => {
                if (item.index == 0) {
                    item.node.setPosition(x + 5, y)
                } else if (item.index == 1) {
                    item.node.setPosition(x, y + 5)
                } else if (item.index == 2) {
                    item.node.setPosition(x - 5, y)
                } else {
                    item.node.setPosition(x, y - 5)
                }
            })
        }
    }

    // 切换回合
    onRoundTurn(isAdd: boolean = true) {
        if (isAdd) {
            DataManager.instance.round += 1
            if (DataManager.instance.round >= 4) DataManager.instance.round = 0
            // 判空
            while (DataManager.instance.posData[DataManager.instance.round].length <= 0) {
                DataManager.instance.round += 1
                if (DataManager.instance.round >= 4) DataManager.instance.round = 0
            }
        }
        StaticInstance.uiManager.setMainDice()
    }

    // 激活棋子与否
    setChessActive(chesses: cc.Node[] = [], status: boolean = true) {
        chesses.forEach(chess => chess.getComponent(Chess).setActive(status))
    }

    // 获取同色棋子
    getChessArrByStep(step: number = -1) {
        let chesses: cc.Node[] = []
        // 起飞号码限制
        const nums = DataManager.instance.canFlyNum[DataManager.instance.canFlyIndex]
        if (step < 0) {
            chesses = this.boardChess.children.filter(chess => chess.getComponent(Chess).type == DataManager.instance.round)
        } else if (nums.indexOf(step) >= 0) {
            chesses = this.boardChess.children.filter(chess => chess.getComponent(Chess).type == DataManager.instance.round && !chess.getComponent(Chess).isEndpoint())
        } else {
            chesses = this.boardChess.children.filter(chess => chess.getComponent(Chess).type == DataManager.instance.round && !chess.getComponent(Chess).isEndpoint() && !chess.getComponent(Chess).isBorn())
        }
        return chesses
    }

    /**
     * ai策略
     * @param chesses cc.Node[]
     * @returns number
     * 1.假设每颗可移动的棋子的初始权重为0
     * 2.直线轨道危险点，权重+2
     * 3.直线轨道安全点，权重-2
     * 3.抵达终点或直线飞行，权重+3
     * 4.所得骰子点数使某颗棋子可以刚好踩死别人的棋子，那么每可踩死一个棋子权重+3
     * 5.某颗棋子后面6格内有别人的棋子，且棋子本身不在安全的位置，（此时可以表示这颗棋子有被踩回家的危险），应该尽快逃离，后面6格内每有一方地方的棋子则权重+3
     */
    getAiIndex(chesses: cc.Node[]) {
        const weight: number[] = []
        chesses.forEach((_, index) => {
            weight[index] = 0
        })
        chesses.forEach((chess, index) => {
            if (chess.getComponent(Chess).pos == 52) {
                weight[index] += 2
            }
            const pos = chess.getComponent(Chess).pos
            const nextPos = pos + this.step
            if (nextPos == 55) {
                weight[index] += 3
            } else {
                if (pos > 49) weight[index] -= 2
            }
            if (nextPos <= 49) {
                if (nextPos == 17) weight[index] += 3
                this.boardChess.children.forEach(other => {
                    if (other != chess && other.getComponent(Chess).type != chess.getComponent(Chess).type) {
                        const otherPos = other.getComponent(Chess).getRoundPosBaseRed()
                        const chessPos = chess.getComponent(Chess).getRoundPosBaseRed(nextPos)
                        if (otherPos == chessPos) {
                            weight[index] += 3
                        }
                    }
                })
            }
            this.boardChess.children.forEach(other => {
                if (other != chess && other.getComponent(Chess).pos >= 0 && chess.getComponent(Chess).pos >= 0 && other.getComponent(Chess).type != chess.getComponent(Chess).type) {
                    const otherPos = other.getComponent(Chess).getRoundPosBaseRed()
                    const chessPos = chess.getComponent(Chess).getRoundPosBaseRed()
                    if (chessPos >= otherPos && chessPos - otherPos <= 6) {
                        weight[index] += 3
                    }
                }
            })
        })

        let mw = -2
        let mi = 0
        weight.forEach((w, i) => {
            if (w > mw) {
                mw = w
                mi = i
            }
        })
        // console.log(weight, mi)
        return mi
    }

    // 服务器同步
    onDicePlaySync({ diceIndex }) {
        DataManager.instance.diceIndex = diceIndex
        const diceComponent = StaticInstance.uiManager.getMainDice()
        diceComponent && diceComponent.play()
    }

    onPlaneTouchSync({ planeIndex, planeType }) {
        const chess = this.boardChess.children.find(chess => chess.getComponent(Chess).type == planeType && chess.getComponent(Chess).index == planeIndex)
        StaticInstance.gameManager.onPlaneTouch(chess.getComponent(Chess))
    }

    onGameOverSync({ room }) {
        DataManager.instance.room = room
        DataManager.instance.status = ENUM_GAME_STATUS.UNRUNING
        StaticInstance.uiManager.toggle(ENUM_UI_TYPE.OVER)
    }

    onGameChatSync({ type, index }) {
        StaticInstance.uiManager.setChatMessage(type, index)
    }

    onGameDisconnectSync({ room }) {
        if (DataManager.instance.status == ENUM_GAME_STATUS.RUNING) {
            // 游戏中, 标记断线用户
            DataManager.instance.room.players.forEach((player, index) => {
                const key = room.players.findIndex((item: any) => item.openid == player.openid)
                if (key < 0) {
                    player.status = 2
                    // 断线玩家由ai接管，继续游戏
                    DataManager.instance.isAi[index] = true
                    if (index == DataManager.instance.round) {
                        StaticInstance.uiManager.setMainDice()
                    }
                }
            })
        }
    }
}
